#include "StdAfx.h"
#include "compressor_main.h"


compressor_main::compressor_main(void)
{
}

compressor_main::~compressor_main(void)
{
}

///////////////////////////////////////////////////////////////////////////////////
//Converts iValue to ascii string in binary of VECTOR_LENGTH
//i.e. VECTOR_LENGTH = 5, iValue = 6 . Then szValue  = 00110
/////////////////////////////////////////////////////////////////////////////


void compressor_main::ItoA(int iValue, char* szValue)
{
	int i;
	int iMask = 1;
	szValue[VECTOR_LENGTH] = '\0';
	for (i = VECTOR_LENGTH - 1; i >= 0; i --)
	{
		szValue[i] = ((iValue & iMask) >> (VECTOR_LENGTH - 1 - i)) + '0';
		iMask = iMask << 1;
	}
}


void compressor_main::CmdLineError(void)
{
}

void compressor_main::InitializeSignals(void)
{
	strcpy(sSignals[V1].szName, "V1");
	strcpy(sSignals[V2].szName, "V2");
	strcpy(sSignals[V3].szName, "V3");
	strcpy(sSignals[V4].szName, "V4");
	strcpy(sSignals[V5].szName, "V5");
	strcpy(sSignals[V6].szName, "V6");
	strcpy(sSignals[CH1].szName, "CH1");
	strcpy(sSignals[CH2].szName, "CH2");
	strcpy(sSignals[CH3].szName, "CH3");
	strcpy(sSignals[CH4].szName, "CH4");
	strcpy(sSignals[CH5].szName, "CH5");
	strcpy(sSignals[VGA1].szName, "VGA1");
	strcpy(sSignals[VGA2].szName, "VGA2");
	strcpy(sSignals[VGA3].szName, "VGA3");
	strcpy(sSignals[VGA4].szName, "VGA4");
	strcpy(sSignals[VGA5].szName, "VGA5");
	strcpy(sSignals[VGA6].szName, "VGA6");
	strcpy(sSignals[SUB].szName, "SUB");
	strcpy(sSignals[PBLK].szName, "PBLK");
	strcpy(sSignals[OB].szName, "OB");
	strcpy(sSignals[DMY].szName, "DMY");
	strcpy(sSignals[HBLK].szName, "HBLK");
	strcpy(sSignals[VIS].szName, "VIS");
	strcpy(sSignals[HIS].szName, "HIS");
	strcpy(sSignals[RESERVED].szName, "RESERVED");
	strcpy(sSignals[ADCLK].szName, "ADCLK");
	strcpy(sSignals[DS2].szName, "DS2");
	strcpy(sSignals[R].szName, "R");
	strcpy(sSignals[HSET].szName, "HSET");
	strcpy(sSignals[HRESET].szName, "HRESET");
}

int compressor_main::FindSignal(const char* szName)
{
	int i;
	for (i = 0; i < VECTOR_LENGTH; i ++)
	{
		if (strcmp(szName, sSignals[i].szName) == 0)
		{
			return i;
		}
	}
	//never found a compatible signal
	return -1;
}



int compressor_main::MakeMatch(FILE* input, int* iMatchArray)
{
	int i;
	char szHeader[1001];
	char* Name;
	char seps[] = " ,\t\n";

	if (fgets(szHeader, 1000, input) == NULL)
	{
		printf("\nMakeMatch: fgets error\n");
		exit(1);
	}
	
	i = 0;
	Name = strtok(szHeader, seps);
	while( Name != NULL )
	{
		iMatchArray[i] = FindSignal(Name);
		if (iMatchArray[i] == -1)
		{
			printf("\nIllegal signals!! Check your file header\n");
			exit(1);
		}
		Name = strtok( NULL, seps );
		i ++;
	}
	return i;
}


void compressor_main::GetFileInfo(FILE* input, int* iNumOfColumns, int* inT)
{
	int i;
	char szFirstLine[1001];
	char seps[] = " \t\n";
	
	if (fgets(szFirstLine, 1000, input) == NULL)
	{
		printf("\nGetFileInfo: fgets error\n");
		exit(1);
	}
	if (strchr(szFirstLine,'s') != NULL)
	{
		*inT = OFF;
	}
	else
	{
		*inT = ON;
	}
	i = 0;
	strtok(szFirstLine, seps);
	while(strtok( NULL, seps ))
	{
	  i ++;
	}
	//if file is in T then T is now in tmp. otherwise units (ns etc) are.
	//NumOfColumns does not include timestamp and time units
	if ( *inT == ON )
	{
		*iNumOfColumns = i;
	}
	else
	{
		*iNumOfColumns = i - 1;
	}
	fseek(input, 0, SEEK_SET);

}

int compressor_main::run_old_main(int argc, char** argv)
{
	//Initializing "globals"
	EFFECTIVE_EDGE	iEffectiveEdge	=		DEFAULT_EFF_EDGE;
	double			ClockCycle		=		1/DEFAULT_CLOCK_CYCLE;
	int				iMaxLineLoopSize=		DEFAULT_LINE_LOOP_SIZE;
	int				iMaxByteLoopSize=		DEFAULT_BYTE_LOOP_SIZE;
	ROUND			iRoundMethod	=		DEFAULT_ROUND;
	int				iHsyncBit		=		HIS;
	unsigned long	ulHtotal		=		DEFAULT_H_TOTAL;
	unsigned long	ulVtotal		=		DEFAULT_V_TOTAL;
	double			Threshhold		=		DEFAULT_THRESHHOLD;
	int				iStat			=		OFF;
	int				iWithRepeats	=		OFF;
	int				iInT			=		OFF;
	int				iOnePass		=		ON;
	
	



	FILE*			Input				=		NULL;
	FILE*			Output				=		NULL;
	FILE*			BinOutput			=		NULL;
	FILE*			Vectors				=		NULL;
	FILE*			Log					=		NULL;
	int				iNumberOfWritten	=		0;
	int				iNumberOfInputs		=		0;
	int				iEEgivenInCmd		=	OFF;
	int				iHtotalGivenInCmd	=	OFF;
	int				iVtotalGivenInCmd	=	OFF;
	int				iColumnsInInput		=	0;
	

	//Will be found by counting the lines in the input file
	int				iVectorsInSlow		=		0;
	int				iVectorsInFirst		=		0;
	int				iVectorsInSecond	=		0;
	int				iNumberOfVectors	=		0;
	int				iVectorsInBlocks	=		0;
	int				iRealVectors		=		0;
	PSVECTOR		sFirstValid			=		NULL;

	//Lines of Vectors - indicated by hsyncs
	unsigned long 	iNumberOfLines		=		0;
	int				iNumberOfBlocks		=		0;
	int				iNumberOfCodeWords	=		0;
	int				iLongVectors		=		0;
	int				iMaxDwordsInLoop	=		0;
	int				iMarkers			=		0;



	PSVECTOR		sVectorArray		=		NULL;
	PSVECTOR		sFirstVectorArray	=		NULL;
	PSVECTOR		sSecondVectorArray	=		NULL;
	PSVECTOR		sFinalVectorArray	=		NULL;
	
	PSLINE			sLineArray			=		NULL;
	PSBLOCK			sBlockArray			=		NULL;
	unsigned int*	iCodeArray			=		NULL;
	int*			iMatchArray			=		NULL;
	int				iBitsNumber			=		0;

	char			szInputFileNames[VECTOR_LENGTH][MAX_FILE_NAME_SIZE];
	char			szIniFileName[MAX_FILE_NAME_SIZE]		= DEFAULT_INI_FILE_NAME;	
	char			szOutputFileName[MAX_FILE_NAME_SIZE]	= { 'o','u','t','p', 'u', 't', 0 };
	
	//Index in main parameter reading
	int i=1;
	int j;
	int k;
	char szVector[VECTOR_LENGTH + 1];

	printf("\nUTG COMPRESSOR Version 1.02\n");
	
	
	InitializeSignals();

	if ( (argc == 1) || (strcmp(argv[i],"-usg") == 0) )
	{
//		printf("\nEncodes (in order to compress) UTG vectors\nFlags:\n"
//				"-ee [int]\n\tThe effective edge of the Hsync bit\n"
//				"\t(1 means Active High, 0 means Active Low, default Active Low).\n"
//				"\tOverrides ini file value.\n"
//				"-htotal [int]\n\tNumber of pixels in a hsync line. Overrides ini file value.\n"
//				"-vtotal [int]\n\tNumber of hsyncs (=lines) in a frame (from vsync to vsync). Overrides ini file value.\n"
//				"-stat\n\tTo get additional output file with statistics\n"
//				"-input [filename(s)]\n\tNames of input files. There must be at least one.\n" 
//				"-output [filename]\n\tName of output file.\n" 
//				"-ini [filename]\n\tName of the ini file\n"
//				"-two_pass\n\tLook for vector resolution loops\n\n\n");
//		exit( 0 );
	}
	
	//Identifying known command line parameters, updating "globals" accordingly
	while (i < argc)
	{			
		//Name of input file for fast signals
		if (strcmp(argv[i],"-ini") == 0)
		{
			if (argv[i+1] == NULL)
			{
				CmdLineError();
			}
			if (szIniFileName == NULL) 
			{
				printf("Out of space! Exiting\n");
				exit(1);
			}
			strcpy(szIniFileName,argv[i+1]);
			i+=2;
			continue;
		}
		//Effective edge
		if (strcmp(argv[i],"-ee") == 0)
		{
			if (argv[i+1] == NULL)
			{
				CmdLineError();
			}
			iEffectiveEdge = (EFFECTIVE_EDGE)	atoi(argv[i+1]);
			iEEgivenInCmd = ON;
			if ( (iEffectiveEdge > 1) || (iEffectiveEdge < 0) )
			{
				CmdLineError();
			}
			i+=2;
			continue;
		}

				
		if (strcmp(argv[i],"-htotal") == 0)
		{
			if (argv[i+1]==NULL)
			{
				CmdLineError();
			}
			ulHtotal = (atoi(argv[i+1])); 
			if (ulHtotal < 1)
			{
				printf("Illegal htotal value! Exiting..\n");
				exit(1);
			}
			iHtotalGivenInCmd = ON;
			i+=2;
			continue;
		}
		
		if (strcmp(argv[i],"-vtotal") == 0)
		{
			if (argv[i+1]==NULL)
			{
				CmdLineError();
			}
			ulVtotal = (atoi(argv[i+1]));
			if (ulVtotal < 1)
			{
				printf("Illegal vtotal value! Exiting..\n");
				exit(1);
			}
			iVtotalGivenInCmd = ON;
			i+=2;
			continue;
		}
		
#ifdef DEBUG
		//Rounding method for calculating Cycles per vector
		if (strcmp(argv[i],"-round") == 0)
		{
			if (argv[i+1] == NULL)
			{
				CmdLineError();
			}
			if (strcmp(argv[i+1],"floor") == 0)
			{
				iRoundMethod = FLOOR;
			}
			if (strcmp(argv[i+1],"ceiling") == 0)
			{
				iRoundMethod = CEILING;
			}
			if (strcmp(argv[i+1],"closest") == 0)
			{
				iRoundMethod = CLOSEST;
			}

			i+=2;
			continue;
		}
		//maximum lines in a loop                                                                                                                                                                                                                 
		if (strcmp(argv[i],"-max_lines") == 0)
		{
			if (argv[i+1]==NULL)
			{
				CmdLineError();
			}
			iMaxLineLoopSize = (atoi(argv[i+1]));
			i+=2;
			continue;
		}
		//maximum bytes in a loop                                                                                                                                                                                                                 
		if (strcmp(argv[i],"-max_bytes") == 0)
		{
			if (argv[i+1]==NULL)
			{
				CmdLineError();
			}
			iMaxByteLoopSize = (atoi(argv[i+1]));
			i+=2;
			continue;
		}
#endif

		
		//get statistics - vectors file
		if (strcmp(argv[i],"-stat") == 0)
		{
			iStat = ON;
			printf("Stat is on.\n");
			i++;
			continue;
		}
		//Dont look for inner (vector) loops
		if (strcmp(argv[i],"-two_pass") == 0)
		{
			iOnePass = OFF;
			printf("Will not look for Vector loops. One pass mode. \n");
			i++;
			continue;
		}

		//Name of input file for fast signals
		if (strcmp(argv[i],"-input") == 0)
		{
			if (argv[i+1] == NULL)
			{
				CmdLineError();
			}
			i ++;
			j = 0;
			while (argv[i][0] != '-')
			{
				strcpy(szInputFileNames[j++],argv[i++]);
				if (j >= VECTOR_LENGTH)
				{
					printf("\nToo many input files\n");
					exit(1);
				}
				iNumberOfInputs = j;
			}
			continue;
		}

		//Name of output file
		if (strcmp(argv[i],"-output") == 0)
		{
			if (argv[i+1] == NULL)
			{
				CmdLineError();
			}
			i ++;
			strcpy(szOutputFileName,argv[i++]);
			continue;
		}
		
	
		//Unknown command line parameter
		CmdLineError();
		
		
	}//while
	
	
	//DEBUG	
	printf("Command line processing complete\n");
	
	
	//Dealing with .ini file
	if (szIniFileName == NULL)
	{
		strcpy(szIniFileName,DEFAULT_INI_FILE_NAME);
	}
	if (iEEgivenInCmd == OFF)
	{
		iEffectiveEdge = (EFFECTIVE_EDGE)GetPrivateProfileInt("sensor","ee",BAD_EFF_EDGE,szIniFileName);
		if (iEffectiveEdge < 0 || iEffectiveEdge > 1)
		{
			printf("\nIllegal effective edge value\n");
			exit(1);
		}
	}
	if (iHtotalGivenInCmd = OFF)
	{
		ulHtotal = GetPrivateProfileInt("sensor","h_total",BAD_H_TOTAL,szIniFileName);
		if (ulHtotal < 0 )
		{
			printf("\nIllegal h_total value\n");
			exit(1);
		}
	}

	if (iVtotalGivenInCmd = OFF)
	{
		ulVtotal = GetPrivateProfileInt("sensor","v_total",BAD_V_TOTAL,szIniFileName);
		if (ulVtotal < 0 )
		{
			printf("\nIllegal h_total value\n");
			exit(1);
		}
	}
	
								
	//printf("%d %lf %s \n",iEffectiveEdge, ClockCycle, szTmp);
	//exit(1);
	Input = fopen(szInputFileNames[0],"r");
	if (Input == NULL)
	{
		printf ("\nUnable to open file %s\n", szInputFileNames[0]);
		exit(1);
	}
	
	iMatchArray = (int*)malloc(VECTOR_LENGTH* sizeof(int));
	iBitsNumber = MakeMatch(Input, iMatchArray);

	GetFileInfo(Input,&iColumnsInInput, &iInT);
	iNumberOfVectors = mfrom_file.CountVectors(Input, iColumnsInInput, iInT);

	sVectorArray = (PSVECTOR)malloc((iNumberOfVectors) * sizeof(SVECTOR));
	if (sVectorArray == NULL)
	{
		printf("Not enough memory. Exiting..");
		exit(1);
	}
	//Extracting vectors from input file to sVectorArray
	iNumberOfVectors = mfrom_file.ParseData(	Input,
												iColumnsInInput,
												&sVectorArray, 
												iNumberOfVectors, 
												iInT,
												iMatchArray,
												iBitsNumber
											);

	iNumberOfVectors = mfrom_file.LeaveNoRepeats(sVectorArray,iNumberOfVectors,&sVectorArray);

//	Allocating array of lines (defined by active state of hsync bit)
	sLineArray = (PSLINE)malloc(iNumberOfVectors * sizeof(SLINE));
	if (sLineArray == NULL)
	{
		printf("Not enough memory. Exiting..");
		exit(1);
	}

	//Marking the lines (first, last vectors in a line) 
	//according to active state of hsync bit 
	iNumberOfLines = mblock.FindLines(	sVectorArray,
											iNumberOfVectors,
											HIS,
											iEffectiveEdge,
											&sLineArray
										);
	
		//Statistics
// imp
/*	printf("Input file: %s Parse data complete with %d, found %d lines\n", 
			szInputFileNames[0],
			iNumberOfVectors, 
			iNumberOfLines);
*/	
	if (iNumberOfLines < ulVtotal)
	{
		printf("\nInput file %s: "
			   "There are %d lines in the input, as opposed to %d = vtotal\n." 
			   "Please check you input files. Exiting..\n", 
			   szInputFileNames[0],
			   iNumberOfLines, 
			   ulVtotal);
		exit(1);
	}
	if (iNumberOfLines > ulVtotal)
	{
		printf("\nNOTICE! There are more lines in the input %s (%d) than vtotal\n"
			   "Only the first %d lines will be encoded\n",
			   szInputFileNames[0],
			   iNumberOfLines,
			   ulVtotal);
		iNumberOfLines = ulVtotal;
	}
		
	if (iInT == OFF)
	{
		//IMPORTANT!!!!
		ClockCycle = (sLineArray[2].sFirst->Absolute - sLineArray[1].sFirst->Absolute)/ulHtotal;
			
		mfrom_file.UpdatePhases(sLineArray, iNumberOfLines, HIS, ClockCycle, sSignals);
		mblock.ToCycles(&sLineArray, iNumberOfLines, ClockCycle, iRoundMethod, sSignals, ulHtotal);
	}
	
	
	sFirstValid = sLineArray[0].sFirst;
	for (i = 1; i < iNumberOfInputs; i ++)
	{

		if (sFirstVectorArray != NULL)
		{
			free(sFirstVectorArray);
		}

		sFirstVectorArray = (PSVECTOR)malloc((iNumberOfVectors) * sizeof(SVECTOR));
		if (sFirstVectorArray == NULL)
		{
			printf("Not enough memory. Exiting..");
			exit(1);
		}
		iVectorsInFirst = iNumberOfVectors - (sFirstValid - sVectorArray);
		
		for (j = 0; j <iVectorsInFirst; j ++)
		{
			mblock.CopyVector(sFirstVectorArray+j, sFirstValid+j);
		}

		Input = fopen(szInputFileNames[i],"r");
		if (Input == NULL)
		{
			printf ("\nUnable to open file %s\n", szInputFileNames[i]);
			exit(1);
		}
		
		if (iMatchArray != NULL)
		{
			free(iMatchArray);
		}
		iMatchArray = (int*)malloc(VECTOR_LENGTH* sizeof(int));
		iBitsNumber = MakeMatch(Input, iMatchArray);

		GetFileInfo(Input,&iColumnsInInput, &iInT);
		
		
		iVectorsInSecond = mfrom_file.CountVectors(Input, iColumnsInInput, iInT);

		//Allocating array of vectors for slow signals
		
		if (sSecondVectorArray != NULL)
		{
			free(sSecondVectorArray);
		}

		sSecondVectorArray = (PSVECTOR)malloc((iVectorsInSecond) * sizeof(SVECTOR));
		if (sSecondVectorArray == NULL)
		{
			printf("Not enough memory. Exiting..");
			exit(1);
		}
		//Extracting vectors from input file to sVectorArray
		iVectorsInSecond = mfrom_file.ParseData(	Input,
													iColumnsInInput,
													&sSecondVectorArray, 
													iVectorsInSecond, 
													iInT,
													iMatchArray,
													iBitsNumber
												);
		iVectorsInSecond = mfrom_file.LeaveNoRepeats(sSecondVectorArray,iVectorsInSecond,&sSecondVectorArray);

		if (sLineArray != NULL)
		{
			free(sLineArray);
		}

		//Allocating array of lines (defined by active state of hsync bit)
		sLineArray = (PSLINE)malloc(iVectorsInSecond * sizeof(SLINE));
		if (sLineArray == NULL)
		{
			printf("Not enough memory. Exiting..");
			exit(1);
		}
		//Marking the lines (first, last vectors in a line) 
		//according to active state of hsync bit 
		iNumberOfLines = mblock.FindLines(	sSecondVectorArray,
											iVectorsInSecond,
											HIS,
											iEffectiveEdge,
											&sLineArray
										);
		//Statistics
		printf("Input file: %s Parse data complete with %d, found %d lines\n", 
				szInputFileNames[i],
				iVectorsInSecond,
				iNumberOfLines);

		if (iNumberOfLines < ulVtotal)
		{
			printf("\nInput file %s: "
				   "There are %d lines in the input, as opposed to %d = vtotal\n." 
				   "Please check you input files. Exiting..\n", 
				   szInputFileNames[i],
				   iNumberOfLines, 
				   ulVtotal);
			exit(1);
		}
		if (iNumberOfLines > ulVtotal)
		{
			printf("\nNOTICE! There are more lines in the input %s (%d) than vtotal\n"
				   "Only the first %d lines will be encoded\n",
				   szInputFileNames[i],
				   iNumberOfLines,
				   ulVtotal);
			iNumberOfLines = ulVtotal;
		}
		
		if (iInT == OFF)
		{
			//IMPORTANT!!!!
			ClockCycle = (sLineArray[2].sFirst->Absolute - sLineArray[1].sFirst->Absolute)/ulHtotal;
			
			mfrom_file.UpdatePhases(sLineArray, iNumberOfLines, HIS, ClockCycle, sSignals);
			mblock.ToCycles(&sLineArray, iNumberOfLines, ClockCycle, iRoundMethod, sSignals, ulHtotal);
		}	
		
		iVectorsInSecond -= (sLineArray[0].sFirst - sSecondVectorArray);
		if (sVectorArray != NULL)
		{
			free(sVectorArray);
		}

		sVectorArray = (PSVECTOR)malloc((iVectorsInFirst+iVectorsInSecond) * sizeof(SVECTOR));
		if (sVectorArray == NULL)
		{
			printf("Not enough memory. Exiting..");
			exit(1);
		}

		iNumberOfVectors = mblock.Merge(sFirstVectorArray,iVectorsInFirst,sLineArray[0].sFirst,iVectorsInSecond,&sVectorArray );
		sFirstValid = &sVectorArray[0];
	}


//now we have a merged vector array which includes inputs from all files
//free no longer needed memory
	if (sSecondVectorArray != NULL)
	{
		free(sSecondVectorArray);
	}
	
	if (sFirstVectorArray != NULL)
	{
		free(sFirstVectorArray);
	}
	
	
//	i = UpdateCycles(&sVectorArray,iNumberOfVectors,ClockCycle, iRoundMethod);

	sFinalVectorArray = (PSVECTOR)malloc(iNumberOfVectors*sizeof(SVECTOR));
	iRealVectors = mfrom_file.RemoveZeros(sVectorArray,iNumberOfVectors, &sFinalVectorArray,0);
	
	i = mblock.UpdateCycles(&sFinalVectorArray,iRealVectors,ClockCycle, iRoundMethod, ulHtotal, ulVtotal);
	
	if (i != iRealVectors)
	{
		printf ("There are still %d Zero Vectors despite RemoveZeros!\n",
				i - iRealVectors);
	}
	iRealVectors = i;
	printf ("After update cycles ther were %d vectors left!\n", iRealVectors);
	

	if (sLineArray != NULL)
	{
		free(sLineArray);
	}

	//Update line array

	sLineArray = (PSLINE)malloc(iNumberOfVectors * sizeof(SLINE));
	if (sLineArray == NULL)
	{
		printf("Not enough memory. Exiting..");
		exit(1);
	}

	//Marking the lines (first, last vectors in a line) 
	//according to active state of hsync bit 
	iNumberOfLines = mblock.FindLines(sFinalVectorArray,iRealVectors,HIS,iEffectiveEdge,&sLineArray);
	printf("Finally number of lines in merged file: %d\n", iNumberOfLines);


	if (iNumberOfLines > ulVtotal)
	{
		printf("\nNOTICE! There are more lines in the merged file (%d) than vtotal\n"
			   "Only the first %d lines will be encoded\n",
			   szInputFileNames[i],
			   iNumberOfLines,
			   ulVtotal);
		iNumberOfLines = ulVtotal;
	}
	//Allocating array of blocks
	sBlockArray = (PSBLOCK)malloc(iNumberOfLines * sizeof(SBLOCK));
	if (sBlockArray == NULL)
	{
		printf("Not enough memory. Exiting..");
		exit(1);
	}
	
	//Allocating LoopData (struct) fields in each block
	for (i = 0; i < (int)iNumberOfLines; i ++)
	{
		//Not likely to fail.
		sBlockArray[i].sLoopData = (PSLOOP)malloc(sizeof(SLOOP));
	}
	
	//Building the block array: LOOP blocks, FLAT blocks
	//Marking first.last vector in a block, and info about the loop if needed 
	printf("PASS 1:\n");
	iNumberOfBlocks = mblock.MarkLoops(sLineArray,iNumberOfLines,&sBlockArray, iMaxLineLoopSize);
	
	//Statistics
	printf("MarkLoops complete with %d\n", iNumberOfBlocks);
	
	if (iOnePass == OFF)
	{
		printf("PASS 2:\n");
		iNumberOfBlocks = mblock.FindMoreLoops(&sBlockArray, iNumberOfBlocks, iMaxByteLoopSize);

		//Statistics
		printf("FindMoreLoops complete with %d\n", iNumberOfBlocks);
	}

	//Allocating buffer of encoded words
	iCodeArray = (unsigned int*)calloc(iRealVectors*2 , sizeof(unsigned int));
	if (iCodeArray == NULL)
	{
		printf("Not enough memory. Exiting..");
		exit(1);
	}


	//Encoding the vector array, using the devision to blocks
	//Output in iCodeArray
	iNumberOfCodeWords = mencoding.EncodeBlock(sBlockArray,iNumberOfBlocks,iCodeArray,&iLongVectors,&iMaxDwordsInLoop,&iMarkers);
	//Statistics
	printf("Encoding finished. %d code words were used\n", iNumberOfCodeWords);

	
	strcat( szOutputFileName, ".txt" );
	Output = fopen(szOutputFileName,"wt");
	if (Output == NULL)
	{
		printf("Cannot create output.txt file. Exiting..\n");
		exit(1);
	}

	for ( i = 0; i < iNumberOfCodeWords; i++)
	{	
		fprintf(Output, "%08x\n", iCodeArray[i] );
	}
	

	/////////////////////////////////////////////////////////////////////////////
	
	strcpy( &szOutputFileName[strlen(szOutputFileName) - 3], "bin" );
	BinOutput = fopen(szOutputFileName,"wb");
	if (BinOutput == NULL)
	{
		printf("Cannot create output.bin file. Exiting..\n");
		exit(1);
	}
	i = fwrite(&((unsigned  long)iNumberOfLines),sizeof(unsigned long),1,BinOutput);
	if (i < 1) 
	{
		printf("fwrite error\n");
		exit(1);
	}

	// Need to swap the bytes in each 32bit value, in order for the file to be readable by COACH.
	for ( i = 0 ; i < iNumberOfCodeWords ; i++ )
	{
		char* pchTemp = (char*)&iCodeArray[i]; 

		fwrite( &pchTemp[3], 1, 1, BinOutput );
		fwrite( &pchTemp[2], 1, 1, BinOutput );
		fwrite( &pchTemp[1], 1, 1, BinOutput );
		fwrite( &pchTemp[0], 1, 1, BinOutput );
	}

	//Creating vectors file to diff with decoded output
	Vectors = fopen("vectors.txt","w");
	if (Vectors == NULL)
	{
		printf("Cannot create vectors file. Exiting..\n");
		exit(1);
	}

	if (iStat == ON)

	{
		//Writing vectors (every vector cycle times) in <binary string> (<cycles>) format 
		//into vectors.txt

		for ( i = 0; i < (int)iNumberOfLines; i++)
		{
			fprintf(Vectors,"Line number %d:\n",i);
			for (j = 0; j < (sLineArray[i].sLast - sLineArray[i].sFirst + 1); j++)
			{
				//if ((sLineArray[i].sFirst + j)->iCycles > 0)
				{
					ItoA((sLineArray[i].sFirst + j)->iValue,szVector);
					fprintf(Vectors,"%s\t\t(%lf)\n",szVector,(sLineArray[i].sFirst + j)->Absolute);
				}
			}
						
		}
	}
	else
	{
		//Writing vectors (every vector cycle times) in <hex> format 
		//into vectors.txt
		for ( i = 0; i < (int)iNumberOfLines; i++)
		{
			for (j = 0; j < (sLineArray[i].sLast - sLineArray[i].sFirst + 1); j++)
			{
				{
					for (k = 0; k < (sLineArray[i].sFirst + j)->iCycles; k ++)
					{
						fprintf(Vectors,"%08x\n",(sLineArray[i].sFirst + j)->iValue);
					}
				}
			}
						
		}
	}

	Log = fopen("statistics.txt","wt");
	if (Vectors == NULL)
	{
		printf("Cannot create statistics file. Exiting..\n");
		exit(1);
	}
	fprintf(Log, "In the encoded file:\n"
				 "%d vectors were detected, %d were left after UpdateCycles\n"				
				 "%d Lines and %d blocks were found\n"
				 "%d vectors encoded as Long Vectors (32 bit vector + 32 bit repeat).\n"
				 "%d vectors encoded as Short Vectors (16 bit = vector + repeat).\n"
				 "%d code words were used as markers.\n"
				 "There were maximum %d dwords (32 bit) in loop body (including the\n"
				 "dword before StartLoop marker).\n"
				 "Alltogether %d code words (32 bit) were used in the encoding.\n",
				 iVectorsInSlow,
			     iRealVectors,
				 iNumberOfLines,
				 iNumberOfBlocks,
				 iLongVectors,
				 iNumberOfCodeWords - iMarkers - (2*iLongVectors),
				 iMarkers,
				 iMaxDwordsInLoop,
				 iNumberOfCodeWords);
//#ifdef DEBUG	
	for (i = 0; i < (int)iNumberOfLines - 1; i ++)
	{
		fprintf(Log, "Line number %d\n"
					 "\tfirst:\n"
					 "\t\tvalue: %x\n"
					 "\t\tlasts: %lf\n"
					 "\tlast:\n"
					 "\t\tvalue: %x\n",
					 i,
					 sLineArray[i].sFirst->iValue,
					 sLineArray[i+1].sFirst->Absolute - sLineArray[i].sFirst->Absolute,
					 sLineArray[i].sLast->iValue);
	}

//#endif


	

/*

	//Release resourses:
//	for (i = 0; i < iColumnsInFast; i ++)
	{
//		free(sFastColumnArray[i].sWhere);
		//FreeWhereList(sFastColumnArray[i].sWhere);
	}
//	free(sFastColumnArray);
//	for (i = 0; i < iColumnsInSlow; i ++)
	{
//		FreeWhereList(sSlowColumnArray[i].sWhere);
	}
//	free(sSlowColumnArray);

*/

	free(sVectorArray);
	free(sFinalVectorArray);
	free(iCodeArray);
	free(sBlockArray);
	free(sLineArray);
//	free(sSlowVectorArray);
//	if (sVectorArray != NULL) free(sVectorArray);

	fclose(Input);
	fclose (Output);
	fclose (BinOutput);
	fclose(Vectors);
	fclose(Log);
	

	return 0;
}
